const locationService = require('../utils/locationService');
const catchAsync = require('../utils/catchAsync');
const AppError = require('../utils/appError');
const { validationResult } = require('express-validator');

// 地址解析为坐标
exports.geocodeAddress = catchAsync(async (req, res, next) => {
  // 检查验证错误
  const errors = validationResult(req);
  if (!errors.isEmpty()) {
    return next(new AppError('输入数据验证失败', 400, errors.array()));
  }

  const { address, city } = req.body;

  const result = await locationService.geocodeAddress(address, city);

  res.status(200).json({
    status: 'success',
    data: {
      coordinates: {
        lng: result.lng,
        lat: result.lat
      },
      formattedAddress: result.formattedAddress,
      confidence: result.confidence
    }
  });
});

// 坐标反解析为地址
exports.reverseGeocode = catchAsync(async (req, res, next) => {
  // 检查验证错误
  const errors = validationResult(req);
  if (!errors.isEmpty()) {
    return next(new AppError('输入数据验证失败', 400, errors.array()));
  }

  const { lng, lat } = req.body;

  const result = await locationService.reverseGeocode(lng, lat);

  res.status(200).json({
    status: 'success',
    data: result
  });
});

// 计算两点间距离
exports.calculateDistance = catchAsync(async (req, res, next) => {
  // 检查验证错误
  const errors = validationResult(req);
  if (!errors.isEmpty()) {
    return next(new AppError('输入数据验证失败', 400, errors.array()));
  }

  const { origin, destination } = req.body;

  const distance = locationService.calculateDistance(
    origin.lng,
    origin.lat,
    destination.lng,
    destination.lat
  );

  res.status(200).json({
    status: 'success',
    data: {
      distance,
      unit: 'km'
    }
  });
});

// 获取路线信息
exports.getRouteInfo = catchAsync(async (req, res, next) => {
  // 检查验证错误
  const errors = validationResult(req);
  if (!errors.isEmpty()) {
    return next(new AppError('输入数据验证失败', 400, errors.array()));
  }

  const { origin, destination, strategy = '0' } = req.body;

  const routeInfo = await locationService.getRouteInfo(
    origin.lng,
    origin.lat,
    destination.lng,
    destination.lat,
    strategy
  );

  res.status(200).json({
    status: 'success',
    data: routeInfo
  });
});

// 查找附近的护理员
exports.findNearbyCaregivers = catchAsync(async (req, res, next) => {
  // 检查验证错误
  const errors = validationResult(req);
  if (!errors.isEmpty()) {
    return next(new AppError('输入数据验证失败', 400, errors.array()));
  }

  const {
    lng,
    lat,
    radius = 10,
    skills,
    minRating,
    maxPrice,
    emergencyService,
    overnightCare
  } = req.query;

  const filters = {
    skills: skills ? skills.split(',') : undefined,
    minRating: minRating ? Number(minRating) : undefined,
    maxPrice: maxPrice ? Number(maxPrice) : undefined,
    emergencyService: emergencyService === 'true',
    overnightCare: overnightCare === 'true'
  };

  const caregivers = await locationService.findNearbyCaregivers(
    Number(lng),
    Number(lat),
    Number(radius),
    filters
  );

  res.status(200).json({
    status: 'success',
    results: caregivers.length,
    data: {
      caregivers
    }
  });
});

// 智能推荐护理员
exports.recommendCaregivers = catchAsync(async (req, res, next) => {
  // 检查验证错误
  const errors = validationResult(req);
  if (!errors.isEmpty()) {
    return next(new AppError('输入数据验证失败', 400, errors.array()));
  }

  const orderInfo = req.body;

  const recommendations = await locationService.recommendCaregivers(orderInfo);

  res.status(200).json({
    status: 'success',
    results: recommendations.length,
    data: {
      recommendations
    }
  });
});

// 获取支持的城市列表
exports.getSupportedCities = catchAsync(async (req, res, next) => {
  const cities = await locationService.getSupportedCities();

  res.status(200).json({
    status: 'success',
    results: cities.length,
    data: {
      cities
    }
  });
});

// 验证地址有效性
exports.validateAddress = catchAsync(async (req, res, next) => {
  // 检查验证错误
  const errors = validationResult(req);
  if (!errors.isEmpty()) {
    return next(new AppError('输入数据验证失败', 400, errors.array()));
  }

  const { address, city } = req.body;

  const isValid = await locationService.validateAddress(address, city);

  res.status(200).json({
    status: 'success',
    data: {
      isValid,
      address,
      city
    }
  });
});

// 获取护理员服务范围内的区域
exports.getCaregiverServiceAreas = catchAsync(async (req, res, next) => {
  const { city } = req.query;

  let query = { status: 'active', isVerified: true };
  if (city) {
    query['serviceArea.city'] = city;
  }

  const Caregiver = require('../models/Caregiver');
  const serviceAreas = await Caregiver.aggregate([
    { $match: query },
    {
      $group: {
        _id: {
          city: '$serviceArea.city',
          district: '$serviceArea.district'
        },
        caregiverCount: { $sum: 1 },
        averageRating: { $avg: '$stats.averageRating' },
        averagePrice: { $avg: '$pricing.baseRate' },
        center: {
          $first: '$serviceArea.coordinates'
        }
      }
    },
    {
      $project: {
        _id: 0,
        city: '$_id.city',
        district: '$_id.district',
        caregiverCount: 1,
        averageRating: { $round: ['$averageRating', 1] },
        averagePrice: { $round: ['$averagePrice', 2] },
        center: 1
      }
    },
    { $sort: { caregiverCount: -1 } }
  ]);

  res.status(200).json({
    status: 'success',
    results: serviceAreas.length,
    data: {
      serviceAreas
    }
  });
});

// 获取热力图数据
exports.getHeatmapData = catchAsync(async (req, res, next) => {
  const { city, bounds } = req.query;

  let query = { status: 'active', isVerified: true };
  if (city) {
    query['serviceArea.city'] = city;
  }

  // 如果提供了边界，只返回边界内的数据
  if (bounds) {
    const [swLng, swLat, neLng, neLat] = bounds.split(',').map(Number);
    query['serviceArea.coordinates'] = {
      $geoWithin: {
        $box: [[swLng, swLat], [neLng, neLat]]
      }
    };
  }

  const Caregiver = require('../models/Caregiver');
  const heatmapData = await Caregiver.find(query)
    .select('serviceArea.coordinates stats.averageRating pricing.baseRate')
    .lean();

  // 转换为热力图格式
  const points = heatmapData.map(caregiver => ({
    lng: caregiver.serviceArea.coordinates[0],
    lat: caregiver.serviceArea.coordinates[1],
    weight: caregiver.stats.averageRating || 3, // 使用评分作为权重
    price: caregiver.pricing.baseRate
  }));

  res.status(200).json({
    status: 'success',
    results: points.length,
    data: {
      points
    }
  });
});

// 获取区域统计信息
exports.getAreaStats = catchAsync(async (req, res, next) => {
  const { lng, lat, radius = 5 } = req.query;

  if (!lng || !lat) {
    return next(new AppError('请提供坐标信息', 400));
  }

  const Caregiver = require('../models/Caregiver');
  const Order = require('../models/Order');

  // 查找区域内的护理员
  const caregivers = await Caregiver.find({
    status: 'active',
    'serviceArea.coordinates': {
      $near: {
        $geometry: {
          type: 'Point',
          coordinates: [Number(lng), Number(lat)]
        },
        $maxDistance: Number(radius) * 1000
      }
    }
  });

  const caregiverIds = caregivers.map(c => c._id);

  // 统计区域内的订单信息
  const orderStats = await Order.aggregate([
    {
      $match: {
        caregiver: { $in: caregiverIds },
        status: 'completed'
      }
    },
    {
      $group: {
        _id: null,
        totalOrders: { $sum: 1 },
        averageRating: { $avg: '$reviews.customer.rating' },
        totalRevenue: { $sum: '$payment.amount' }
      }
    }
  ]);

  const stats = {
    caregiverCount: caregivers.length,
    averageRating: caregivers.reduce((sum, c) => sum + (c.stats.averageRating || 0), 0) / caregivers.length || 0,
    averagePrice: caregivers.reduce((sum, c) => sum + c.pricing.baseRate, 0) / caregivers.length || 0,
    totalOrders: orderStats[0]?.totalOrders || 0,
    totalRevenue: orderStats[0]?.totalRevenue || 0,
    radius: Number(radius)
  };

  res.status(200).json({
    status: 'success',
    data: {
      stats: {
        ...stats,
        averageRating: Math.round(stats.averageRating * 10) / 10,
        averagePrice: Math.round(stats.averagePrice * 100) / 100
      }
    }
  });
});